package com.github

//import scalax.io.{
//FileOps, Path, Codec, OpenOption}
import scala.io.Source
import java.util.Date
import java.io.FileWriter
import java.io.BufferedWriter;
import java.io.File;

// the codec must be defined either as a parameter of ops methods or as an implicit
//implicit val codec = scalax.io.Codec.UTF8

/**
 * Created with IntelliJ IDEA.
 * User: manningermatyas
 * Date: 2014.01.10.
 * Time: 21:58
 * To change this template use File | Settings | File Templates.
 */
class Menu {

  var user : String = "mani"
  var pass : String = ""
  var diary : Diary = new Diary(Nil)

  def turnPage(dir : Int) : Unit = {if (dir == 1) {diary = diary.next} else diary = diary.prev}

  def writeList : Unit = {
    println("\033[2J")
    println(diary)
  }

  def writeEntry : Unit = {
    println("\033[2J")
    println(diary.entries.head)
    val x = readLine()
  }

  def loadData : Unit = {
    val a = Source.fromURL(getClass.getResource("/" + user + ".man"))
    val list = a.getLines().toList.map(x => x.map(y => y - 1).map(x => x.toChar).mkString)
    //val list = a.getLines().toList
    pass = list.head.drop(user.length).tail           //c => c == ':'
    val listOfLines = list.tail
    def buildList(l : List[String]) : List[List[String]] = l match {
      case Nil => Nil
      case xs =>  (l.head :: l.tail.takeWhile(s => (s != "LE" && s != "SE" && s != "LI"))) ::
        buildList(l.tail.dropWhile(s => (s != "LE" && s != "SE" && s != "LI")))
    }
    val listOfEntries = buildList(listOfLines)
    def createEntry(l : List[String]) : Entry = {
      val format = new java.text.SimpleDateFormat("yyyy-MM-dd")
      val date = format.parse(l(1))
      if (l.head == "SE") (new ShortEntry(date, l(2), l(3))) else
        if (l.head == "LI") (new Link(date, l(2), l(3), l(4))) else
        (new LongEntry(date, l(2), l.init.drop(3).flatMap(x => x + '\n').mkString, l.last))
    }
    diary = new Diary(listOfEntries.map(createEntry))
  }

  def login : Unit = {
    println("\033[2J")
    print("Felhasznalnev: ")
    user = readLine()
    loadData
    def passCheck : Unit = {
      print("Jelszo: ")
      val upass = readLine()
      if (pass == upass) () else (passCheck)
    }
    passCheck
  }

  def register : Unit = {
    println("\033[2J")
    print("Felhasznalonev: ")
    user = readLine()
    def readPass : String = {
      println("\033[2J")
      print("Jelszo: ")
      val passone: String = readLine()
      print("Jelszo megegyszer: ")
      val passtwo: String = readLine()
      if (passone == passtwo) (passone) else readPass
    }
    pass = readLine()
  }

  def addEntry : Unit = {

    def readStringWithLengt(l : Int) : String = {
      val s = readLine()
      def reRead(l : Int) : String = {
        print("A szoveg max " + l.toString + " karakter hosszu lehet! Ird ujra: ")
        val news = readLine()
        if (news.length > l) (reRead(l)) else news
      }
      if (s.length > l) (reRead(l)) else s
    }

    def readLong : LongEntry = {
      println("\033[2J")
      print("Cim: ")
      val cim = readStringWithLengt(50)
      print("Osszefoglalo: ")
      val sum = readStringWithLengt(100)
      print("Tartalom (_EOF_ beiras jelzi a bejegyzes veget): ")
      val cont = Iterator.
        continually(Console.readLine).
        takeWhile(_ != "_EOF_").
        mkString("\n")
      val d = new Date()
      new LongEntry(d, cim, cont, sum)
    }

    def readShort : ShortEntry = {
      println("\033[2J")
      print("Cim: ")
      val cim = readStringWithLengt(50)
      print("Bejegyzes: ")
      val cont = readStringWithLengt(500)
      val d = new Date()
      new ShortEntry(d, cim, cont)
    }

    def readLink : Link = {
      println("\033[2J")
      print("Cim: ")
      val cim = readStringWithLengt(50)
      print("Osszefoglalas: ")
      val cont = readStringWithLengt(500)
      print("Link: ")
      val link = readLine()
      val d = new Date()
      new Link(d, cim, link, cont)
    }
    def readEntry : Entry = {
      println("\033[2J")
      println("1. Hosszu bejegyzes\n2. Rovid bejegyzes\n3. Link")
      val entryType = readLine()
      if (entryType == "1") (readLong) else (if (entryType == "2") (readShort) else (if (entryType == "3") (readLink) else readEntry))
    }
    val newEntry : Entry = readEntry
    diary = diary.addEntry(newEntry)
  }

  def saveData : Unit = {
    val file = new FileWriter(user + ".man")
    file.write(user.map(x => x + 1).map(x => x.toChar).mkString + ":" + pass.map(x => x + 1).map(x => x.toChar).mkString + "\n")
    def entryWriter(e : Entry) = e match {
      case a: LongEntry => {
        file.write ("MF\n" + (a.getDate.getYear + 1900).toString.map(x => x + 1).map(x => x.toChar).mkString + "." +
          a.getDate.getMonth.toString.map(x => x + 1).map(x => x.toChar).mkString + "." +
          a.getDate.getDay.toString.map(x => x + 1).map(x => x.toChar).mkString + "\n" +
          a.getTitle.map(x => x + 1).map(x => x.toChar).mkString + "\n" +
          a.getContent.map(x => x match { case '\n' => '\n' case x => x + 1}).map(x => x.toChar).mkString +
          a.getSummary.map(x => x + 1).map(x => x.toChar).mkString + "\n")
        }
      case a: ShortEntry => {
        file.write ("TF\n" + (a.getDate.getYear + 1900).toString.map(x => x + 1).map(x => x.toChar).mkString + "." +
          a.getDate.getMonth.toString.map(x => x + 1).map(x => x.toChar).mkString + "." +
          a.getDate.getDay.toString.map(x => x + 1).map(x => x.toChar).mkString + "\n" +
          a.getTitle.map(x => x + 1).map(x => x.toChar).mkString + "\n" +
          a.getContent.map(x => x + 1).map(x => x.toChar).mkString + "\n")
        }
      case a: Link => {
        file.write ("MJ\n" + (a.getDate.getYear + 1900).toString.map(x => x + 1).map(x => x.toChar).mkString + "." +
          a.getDate.getMonth.toString.map(x => x + 1).map(x => x.toChar).mkString + "." +
          a.getDate.getDay.toString.map(x => x + 1).map(x => x.toChar).mkString + "\n" +
          a.getTitle.map(x => x + 1).map(x => x.toChar).mkString + "\n" +
          a.getLink.map(x => x + 1).map(x => x.toChar).mkString + "\n" +
          a.getAbout.map(x => x + 1).map(x => x.toChar).mkString + "\n")
        }
      }

    diary.entries.map(entryWriter)
    file.close()
  }

  def run : Unit = {
    println("\033[2J")
    println("1. Bejelentkezes \n2. Regisztracio")
    val log = readLine()
    if (log == "1") (login) else register
    def menu : Unit = {
      writeList
      println("------------------------------------------")
      println("1. Lapozas egyet elore\n2. Lapozas egyet vissza\n3. Elso bejegyzes kiirasa\n4. Bejegyzes irasa\nEgyeb: Mentes es kilepes")
      val dec = readLine()
      dec match{
        case "1" => {
          turnPage(1)
          menu
        }
        case "2" => {
          turnPage(2)
          menu
        }
        case "3" => {
          writeEntry
          menu
        }
        case "4" => {
          addEntry
          menu
        }
        case _ => saveData
      }
    }
    menu
  }
}
